package com.carrental.search.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Elasticsearch配置类
 * 用于配置Elasticsearch客户端和操作模板
 */
@Slf4j
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.carrental.search.repository")
@ConditionalOnProperty(name = "spring.elasticsearch.repositories.enabled", havingValue = "true", matchIfMissing = true)
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

    @Value("${spring.elasticsearch.rest.uris}")
    private String uris;

    @Value("${spring.elasticsearch.rest.username}")
    private String username;

    @Value("${spring.elasticsearch.rest.password}")
    private String password;

    @Value("${spring.elasticsearch.rest.connection-timeout:10000}")
    private int connectionTimeout;

    @Value("${spring.elasticsearch.rest.read-timeout:10000}")
    private int readTimeout;

    /**
     * 创建Elasticsearch高级客户端
     *
     * @return RestHighLevelClient
     */
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        try {
            log.info("初始化Elasticsearch客户端，连接到: {}", uris);
            
            // 解析URI列表
            String[] uriArray = uris.split(",");
            List<HttpHost> httpHosts = new ArrayList<>();
            for (String uri : uriArray) {
                httpHosts.add(HttpHost.create(uri));
            }
            
            // 创建RestClientBuilder
            RestClientBuilder builder = RestClient.builder(httpHosts.toArray(new HttpHost[0]))
                    .setRequestConfigCallback(requestConfigBuilder -> 
                            requestConfigBuilder
                                    .setConnectTimeout(connectionTimeout)
                                    .setSocketTimeout(readTimeout))
                    .setHttpClientConfigCallback(httpClientBuilder -> {
                        // 如果配置了用户名和密码，则启用基本认证
                        if (StringUtils.hasText(username) && StringUtils.hasText(password)) {
                            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                            credentialsProvider.setCredentials(AuthScope.ANY,
                                    new UsernamePasswordCredentials(username, password));
                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                        }
                        return httpClientBuilder;
                    });
            
            return new RestHighLevelClient(builder);
        } catch (Exception e) {
            log.error("创建Elasticsearch客户端失败", e);
            throw new RuntimeException("Failed to create Elasticsearch client", e);
        }
    }

    /**
     * 创建ElasticsearchOperations实例
     *
     * @return ElasticsearchOperations
     */
    @Bean
    public ElasticsearchOperations elasticsearchOperations() {
        try {
            return new ElasticsearchRestTemplate(elasticsearchClient());
        } catch (Exception e) {
            log.error("创建ElasticsearchOperations失败", e);
            throw e;
        }
    }
} 